package org.javamianshi.core;


import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author: fanliu
 * @description Type 泛型 反射测试
 * @date: 2024/8/30 14:06
 */
public class TypeTest {

    public static void main(String[] args) throws NoSuchMethodException {
        new TypeTest().showType();
    }


    /**
     * Java 中的所有类型
     *
     *     raw type：原始类型，对应 Class
     *         即我们通常说的引用类型，包括普通的类，例如 String.class、List.class
     *         也包括数组(Array.class)、接口(Cloneable.class)、注解(Annotation.class)、枚举(Enum.class)等
     *     primitive types：基本类型，对应 Class
     *         包括 Built-in 内置类型，例如 int.class、char.class、void.class
     *         也包括 Wrappers 内置类型包装类型，例如 Integer.class、Boolean.class、Void.class
     *     parameterized types：参数化类型，对应 ParameterizedType
     *         带有类型参数的类型，即常说的泛型，例如 List<T>、Map<Integer, String>、List<? extends Number>
     *         实现类 sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
     *     type variables：类型变量类型，对应 TypeVariable<D>
     *         即参数化类型 ParameterizedType 中的 E、K 等类型变量，表示泛指任何类
     *         实现类 sun.reflect.generics.reflectiveObjects.TypeVariableImpl
     *     array types：泛型数组类型，对应 GenericArrayType
     *         元素类型是参数化类型或者类型变量的泛型数组类型，例如 T[]
     *         实现类 sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl
     *
     *     Type 接口的另一个子接口 WildcardType 代表通配符表达式类型，或泛型表达式类型，比如?、? super T、? extends T，他并不是 Java 类型中的一种。
     *
     *
     * @throws NoSuchMethodException
     */
    private void showType() throws NoSuchMethodException {
        // 注意 int.class 和 Integer.class 是不一样的(没有所谓的自动装箱、自动拆箱机制)，不能互用
        Class<?> clazz = List.class;
        Method method = TypeTest.class.getMethod("testType", int.class, Boolean.class,A.class, clazz, clazz, clazz, clazz, clazz, Map.class);
        Type[] genericParameterTypes = method.getGenericParameterTypes(); //按照方法参数声明顺序返回参数的 Type 数组
        for (Type type : genericParameterTypes) {
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                Type[] types = parameterizedType.getActualTypeArguments(); //返回表示此类型【实际类型参数】的 Type 数组
                for (int i = 0; i < types.length; i++) {
                    System.out.println(i + getTypeInfo(types[i]));
                }
            } else {
                System.out.println("  " + getTypeInfo(type));
            }
        }
    }

    private String getTypeInfo(Type type) {
        String typeName = type.getTypeName();
        Class<?> clazz = type.getClass();
        Class<?>[] interfaces = clazz.getInterfaces();
        StringBuilder typeInterface = new StringBuilder();
        for (Class<?> clazzType : interfaces) {
            typeInterface.append(clazzType.getSimpleName()).append(",");
        }
        return "【" + typeName + "】    【" + clazz.getSimpleName() + "】    【" + typeInterface + "】";
    }

    public <T> void testType(int i, Boolean b,A a, List<String> a1, List<ArrayList<String>> a2, List<T> a3, //
                             List<? extends Number> a4, List<ArrayList<String>[]> a5, Map<Boolean, Integer> a6) {
    }

}
